package parser;

import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;



/**
 * @author 490501
 */
public class XMLPArser{
    private DocumentBuilderFactory dbf;
    private DocumentBuilder db;
    private Document dom;

    public Document getDom() {
        return dom;
    }

    public void setDom(Document dom) {
        this.dom = dom;
    }
    
    /**
     * Create new instance of XMLPArser, parse and validate document med hensyn til 
     * modelPrototype.dtd
     */
    public XMLPArser(String pathToXML){
        dbf = DocumentBuilderFactory.newInstance();
        dbf.setValidating(true);
        //разобраться с еррорхандлерами, как они работают и как обрабатывать ошибки
        try {
            db = dbf.newDocumentBuilder();
            dom = db.parse(pathToXML);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(XMLPArser.class.getName()).log(Level.SEVERE, null, ex);
        } catch(IOException ex)  {
            Logger.getLogger(XMLPArser.class.getName()).log(Level.SEVERE, null, ex);
        } catch(SAXException ex) {
            Logger.getLogger(XMLPArser.class.getName()).log(Level.SEVERE, null, ex);
        } 
    }
    

    public String parseElement(String _name) {
        Element element = dom.getDocumentElement();
        return null;
        
    }
    /**
     * returnerer innhold av Description element i xml fila
     * @return HashMap<String,String> that contains all description fields of project 
     */
    public HashMap<String,String> getDescriptionOfProject() {
        HashMap<String,String> hm = new HashMap<String,String>();
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("description");
        Node n = nl.item(0);
        nl = n.getChildNodes();
        for(int i = 0; i < nl.getLength(); i++){
            n = nl.item(i);
            //System.out.println(n.getNodeName() + " " + n.getTextContent());
            if(n.getNodeName().charAt(0) != '#')
            hm.put(n.getNodeName(), n.getTextContent());
        }
        return hm;
    }

    
    /**
     * 
     * @return project name from loaded xml modell 
     */
    public String getProjectName() {
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("description");
        Node n = nl.item(0);
        nl = n.getChildNodes();
        for(int i = 0; i < nl.getLength(); i++){
            n = nl.item(i);
            if(n.getNodeName().equals("project-name"))
                return n.getTextContent();
        }
        return "Not defined";
    }
    

    /**
     * 
     * @return project version from loaded xml file 
     */
    public String getVersion() {
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("description");
        Node n = nl.item(0);
        nl = n.getChildNodes();
        for(int i = 0; i < nl.getLength(); i++){
            n = nl.item(i);
            if(n.getNodeName().equals("version"))
                return n.getTextContent();
        }
        return "Not defined";
    }
    
    /**
     * 
     * @return author name from loaded xml file
     */
    public String getAuthorName() {
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("description");
        Node n = nl.item(0);
        nl = n.getChildNodes();
        for(int i = 0; i < nl.getLength(); i++){
            n = nl.item(i);
            if(n.getNodeName().equals("author-name"))
                return n.getTextContent();
        }
        return "Not defined";
    }
    
    /**
     * 
     * @return project creation date from loaded xml file 
     */
    public String getCreationDate() {
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("description");
        Node n = nl.item(0);
        nl = n.getChildNodes();
        for(int i = 0; i < nl.getLength(); i++){
            n = nl.item(i);
            if(n.getNodeName().equals("creation-date"))
                return n.getTextContent();
        }
        return "Not defined";
    }
    
    /**
     * 
     * @param date 
     */
    public void setCreationDate(String date) {
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("description");
        Node n = nl.item(0);
        nl = n.getChildNodes();
        for(int i = 0; i < nl.getLength(); i++){
            n = nl.item(i);
            if(n.getNodeName().equals("creation-date")) {
                n.setTextContent(date);
                
            }
                
            
        }
    }
    
    /**
     * 
     * @return NodeList of units (hus) from project 
     */
    private NodeList getUnits(){
        Element root = dom.getDocumentElement();
        NodeList nl = root.getElementsByTagName("unit");
        return nl;
    }
    
    /**
     * 
     * @param n
     * @throws ParseException 
     */
    public void parseUnit(Node n) throws ParseException{
        //sjekker om det er unit node eller ikke
        if(!n.getNodeName().equals("unit")){
            throw new ParseException("Node is not unit", 1);
        }
        NodeList nl = n.getChildNodes();
        //parser noder i løkke
        for(int i = 0; i < nl.getLength(); i++){
            Node _n = nl.item(i);
            if(_n.getNodeName().equals("mode")) {
                if(_n.getTextContent().equals("simple"))
                {
                    System.out.println(_n.getTextContent());
                    //parse simple
                    this.parseSimple(nl);
                    return;
                }
                else if(_n.getTextContent().equals("advanced")) {
                    System.out.println(_n.getTextContent());
                    //parse advanced
                    this.parseAdvanced(nl);
                    return;
                }
            }
        }
        throw new ParseException("mode undefined", 1);
    }

    /**
     * 
     * @param _nl NodeList with modell information
     */
    private void parseSimple(NodeList _nl) {
        Project u = new Project();//unit object
        //TODO parse simple modell
        for(int i = 0; i < _nl.getLength(); i++) {
            Node n = _nl.item(i);
            if(n.getTextContent().equals("geometry")) { //parse geometry
                NodeList geometry = n.getChildNodes();
                for(int j = 0; j < geometry.getLength(); j++) {
                    Node _n = geometry.item(j);
                    if(_n.getNodeName().equals("area")) {
                        u.setArea(n.getTextContent());
                        System.out.println(n.getTextContent());
                    }
                    else if(_n.getNodeName().equals("volume")){
                        u.setVolume(n.getTextContent());
                        System.out.println(n.getTextContent());
                    }
                    else if(_n.getNodeName().equals("TECStandard")) {
                        u.setTECStandard(n.getTextContent());
                        System.out.println(n.getTextContent());
                    }
                }
            }
        }
        
        
        //parse ventilasjon node
        //...
    }

    /**
     * 
     * @param _nl 
     */
    private void parseAdvanced(NodeList _nl) {
        //TODO parse advanced modell
        //parse geometry node
        //parse ventilasjon node
        //...
    }
    
    /***************************************************************************/
    //test
    public static void main(String[] args) {
        XMLPArser p = new XMLPArser("src/java/parser/modelPrototype.xml");
        //ModelPrototypeScanner pp = new ModelPrototypeScanner(p.getDom());
        //Project ppp = pp.parseDocument();
        //ppp.getArea();
        p.parseElement("description");

    }
}
